home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / fontutil.6 / fontutil / fontutils-0.6 / limn / xserver.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-05  |  5.6 KB  |  205 lines

  1. /* xserver.c: show pictures of the fitted characters on an X display.
  2.  
  3. Copyright (C) 1992 Free Software Foundation, Inc.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <X11/Intrinsic.h>
  22. #include <X11/StringDefs.h>
  23. #include <X11/Xatom.h>
  24. #include <X11/Xaw/Label.h>
  25. #include <X11/Xaw/Viewport.h>
  26.  
  27. #include "xserver.h"
  28.  
  29. /* For the resource database.  */
  30. #define CLASS_NAME "Limn"
  31.  
  32. /* The root of the widget hierarchy.  */
  33. static Widget top_level;
  34.  
  35. /* The connection to the X server.  */
  36. static Display *display;
  37.  
  38. /* Where we draw the pictures.  */
  39. static Widget canvas_widget;
  40.  
  41. /* The messages we recognize.  */
  42. Atom foserver_exit_atom, foserver_update_pixmap_atom;
  43.  
  44. /* This property contains an identification string for the server.
  45.    The string name is in xserver.h.  */
  46. Atom foserver_identity_atom;
  47.  
  48. /* The type of the `data' member in a ClientMessage event.  */
  49. typedef union
  50. {
  51.   char b[20];
  52.   short s[10];
  53.   long l[5];
  54. } message_data_type;
  55.  
  56. static void dispatch_message (Atom, message_data_type);
  57. static void foserver_exit (void);
  58. static void foserver_update_pixmap (Pixmap);
  59. static void message_handler (Widget, XEvent *, String *, Cardinal *);
  60.  
  61. void
  62. #ifdef STANDALONE_SERVER
  63. main (int argc, char *argv[])
  64. {
  65.   unsigned window_size;
  66.   string identity; /* This will be the contents of `identity_atom'.  */
  67. #else /* not STANDALONE_SERVER */
  68. start_server (unsigned window_size, string identity)
  69. {
  70. #endif /* not STANDALONE_SERVER */
  71.  
  72.   XTextProperty textP;
  73.   Widget viewport_widget;
  74.   int zero = 0;
  75.   
  76.   /* This routine will intercept messages we get.  */
  77.   XtActionsRec actions[] = { { "MessageHandler", message_handler } };
  78.   
  79.   /* Here we assume that all the characters will fit in an em square. 
  80.      (We make further assumptions below.)  The TFM format guarantees
  81.      that the design size is not negative.  Values in the resource
  82.      database override this.  These initial values are only useful if we
  83.      are not standalone, but we reassign just below if we are
  84.      standalone.  */
  85.   Arg geometry_args[]
  86.     = { { XtNheight, window_size },
  87.         { XtNwidth,  window_size },
  88.       };
  89.  
  90. #ifdef STANDALONE_SERVER
  91.   if (argc == 3)
  92.     {
  93.       window_size = atou (argv[1]);
  94.       geometry_args[0].value = geometry_args[1].value = window_size;
  95.       identity = argv[2];
  96.     }
  97.   else
  98.     {
  99.       fprintf (stderr, "Usage: %s window-size identity.\n", argv[0]);
  100.       exit (0);
  101.     }
  102. #endif /* STANDALONE_SERVER */
  103.  
  104.   /* We have no fallback resources, and we've already parsed the args.  */
  105.   top_level = XtInitialize (NULL, CLASS_NAME, NULL, 0, &zero, NULL);
  106.  
  107.   viewport_widget
  108.     = XtCreateManagedWidget ("viewport", viewportWidgetClass, top_level,
  109.                          NULL, 0); 
  110.   canvas_widget
  111.     = XtCreateManagedWidget ("canvas", labelWidgetClass, viewport_widget,
  112.                              geometry_args, XtNumber (geometry_args));
  113.  
  114.   XtAddActions (actions, XtNumber (actions));
  115.  
  116.   XtRealizeWidget (top_level);
  117.   
  118.   display = XtDisplay (top_level);
  119.  
  120.   foserver_exit_atom = XInternAtom (display, FOSERVER_EXIT_ATOM, False);
  121.   foserver_update_pixmap_atom
  122.     = XInternAtom (display, FOSERVER_UPDATE_PIXMAP_ATOM, False);
  123.  
  124.   /* Get the identity atom number. Create it if it doesn't exist.  */
  125.   foserver_identity_atom
  126.     = XInternAtom (display, FOSERVER_IDENTITY_ATOM, False);
  127.  
  128.   textP.value = (unsigned char *) identity; /* Set value.  */
  129.   textP.encoding = XA_STRING;
  130.   textP.format = 8;
  131.   textP.nitems = strlen (identity);
  132.   XSetTextProperty (display, XtWindow (canvas_widget), &textP,
  133.                     foserver_identity_atom);
  134.  
  135.   /* Process events forever.  */
  136.   XtMainLoop ();
  137. }
  138.  
  139.  
  140. static void
  141. message_handler (Widget w, XEvent *event, String *params, Cardinal *n_params)
  142. {
  143.   switch (event->type)
  144.     {
  145.     case ClientMessage:
  146.       {
  147.         XClientMessageEvent m = event->xclient;
  148.         message_data_type d;
  149.         
  150.         /* Because two union types are never equivalent, and the X
  151.            library does not define a type for the data part of the
  152.            event, we must copy the data.  */
  153.         memcpy (&d, &(m.data), sizeof (d.b));
  154.         
  155.         dispatch_message (m.message_type, d);
  156.         break;
  157.       }
  158.  
  159.     default:
  160.       FATAL1 ("foserver: Unexpected event (type %d)", event->type);
  161.     }
  162. }
  163.  
  164.  
  165. /* Call the appropriate routine for the atom A, or give an error.  */
  166.  
  167. static void
  168. dispatch_message (Atom a, message_data_type data)
  169. {
  170.   if (a == foserver_exit_atom)
  171.     foserver_exit ();
  172.   
  173.   else if (a == foserver_update_pixmap_atom)
  174.     foserver_update_pixmap (data.l[0]);
  175.  
  176.   else
  177.     WARNING1 ("foserver: Unknown message `%s'", XGetAtomName (display, a));
  178. }
  179.  
  180. /* Shut down.  */
  181.  
  182. static void
  183. foserver_exit ()
  184. {
  185.   XCloseDisplay (display);
  186.   exit (0);
  187. }
  188.  
  189.  
  190. /* Show a new pixmap.  */
  191.  
  192. static void
  193. foserver_update_pixmap (Pixmap p)
  194. {
  195.   Arg label_args[]
  196.      = { { XtNbitmap, p },
  197.        };
  198.   
  199.   /* Call XtSetValues only after drawing everything, since it
  200.      doesn't particularly matter if what we draw is visible as we
  201.      go.  (In general, because of the asynchronicity of the server,
  202.      it wouldn't be, anyway.)  */
  203.   XtSetValues (canvas_widget, label_args, XtNumber (label_args));
  204. }
  205.